延續昨天的範例,我們將商品用bootstrap的Card Decks排列出來,現在我們有另一個model想用一樣的方式顯示,我們這時候可以將那樣的版面做成通用樣板元件。
首先我們先將版面改成下面這個樣子,有一個標題,一個<hr>標籤,一個Card Decks。
接下來開始改造工作,首先將Card Decks裡的Card,獨立成一個Card元件。
<div class="card">
    <img class="card-img-top" src="@CardImgUrl" alt="Card image cap">
    <div class="card-body">
        <h5 class="card-title">@CardTitle</h5>
        <p class="card-text"><small class="text-muted">@CardSubTitle</small></p>
    </div>
</div>
@code{
    [Parameter]
    public string CardImgUrl { get; set; }
    [Parameter]
    public string CardTitle { get; set; }
    [Parameter]
    public string CardSubTitle { get; set; }
}
GenericCard template元件:
@typeparam TItem
<h3>@Title</h3>
<hr />
<div class="card-deck">
    @foreach (var item in Items)
    {
        @CardTemplate(item)
    }
</div>
@code {
    [Parameter]
    public RenderFragment Title { get; set; }
    [Parameter]
    public RenderFragment<TItem> CardTemplate { get; set; }
    [Parameter]
    public IReadOnlyList<TItem> Items { get; set; }
}
IReadOnlyList<TItem> Items:接收要顯示的list資料RenderFragment<TItem> CardTemplate:接收多個Card元件Productlist改套用GenericCard template:
<GenericCard Items="products">
        <Title>
            <h2>Fruit</h2>
        </Title>
       <CardTemplate>
            <Card CardImgUrl="@context.ImgUrl" CardTitle="@context.ProductName" CardSubTitle="@context.Price.ToString("C")"></Card>
        </CardTemplate>
    </GenericCard>
<GenericCard Items="products">
        <Title>
            <h2>Fruit</h2>
        </Title>
        <CardTemplate Context="product">
            <Card CardImgUrl="@product.ImgUrl" CardTitle="@product.ProductName" CardSubTitle="@product.Price.ToString()"></Card>
        </CardTemplate>
    </GenericCard>
<GenericCard Items="products" Context="product">
        <Title>
            <h2>Fruit</h2>
        </Title>
        <CardTemplate>
            <Card CardImgUrl="@product.ImgUrl" CardTitle="@product.ProductName" CardSubTitle="@product.Price.ToString()"></Card>
        </CardTemplate>
    </GenericCard>
最後,我們製作一個SuperHeroes元件,準備好資料後,就可以套用GenericCard template啦
@if (heroes.Count == 0)
{
    <img src="https://media.giphy.com/media/3oEjI6SIIHBdRxXI40/giphy.gif" />
}
else
{
    <GenericCard Items="heroes">
        <Title>
            <h2 class="text-primary">Super Heroes</h2>
        </Title>
        <CardTemplate Context="hero">
            <Card CardImgUrl="@hero.ImgUrl" CardTitle="@hero.Name" CardSubTitle="@hero.RealName"></Card>
        </CardTemplate>
    </GenericCard>
}
@code {
    List<Hero> heroes = new List<Hero>();
    protected override async Task OnInitializedAsync()
    {
        await Task.Delay(1000);
        heroes.Add(new Hero() { Id = 1, Name = "Iron Man", ImgUrl = "https://terrigen-cdn-dev.marvel.com/content/prod/1x/002irm_ons_crd_03.jpg", RealName = "Tony Stark" });
        heroes.Add(new Hero() { Id = 1, Name = "Captain America", ImgUrl = "https://terrigen-cdn-dev.marvel.com/content/prod/1x/003cap_ons_crd_03.jpg", RealName = "Steve Rogers" });
        heroes.Add(new Hero() { Id = 1, Name = "Hulk", ImgUrl = "https://terrigen-cdn-dev.marvel.com/content/prod/1x/006hbb_ons_crd_03.jpg", RealName = "Bruce Banner" });
        base.OnInitialized();
    }
}
